import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import glob

criteria=(cv.TERM_CRITERIA_EPS +cv.TERM_CRITERIA_MAX_ITER,30,0.001)
#设置寻找亚像素角点的参数，采用的停止准则是最大循环次数30和最大误差容限0.001
w=8
h=7#这里的w,h是棋盘格横向纵向角点数，不是格子数
objp=np.zeros((w*h,3),np.float32)#3D点称为object points，2D图像点称为image points
objp[:,:2]=np.mgrid[0:h,0:w].T.reshape(-1,2)
obj_points=[]#储存3D点，世界坐标的3维点
img_points=[]#储存2D点，图像平面2维点
images=glob.glob('F:\AI\data\left*.jpg')
i=0
for fname in images:
    img=cv.imread(fname)
    gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    size=gray.shape[::-1]
    ret,corners=cv.findChessboardCorners(gray,(w,h),None)
    #标定板内角点，传入图像是8位灰度或彩色图，patternSize是板内角点行列数


    if ret:#寻找足够的角点
        obj_points.append(objp)
        corners2=cv.cornerSubPix(gray,corners,(5,5),(-1,-1),criteria)
        #提高精度，在上一步提取角点信息上进一步提取亚像素信息，winsize（5，5）为搜索窗口一半
        #zeroZone死区一半，（-1，-1）没有死区；criteria为角点迭代终止条件
        if[corners2]:
            img_points.append(corners2)
        else:
            img_points.append(corners)
        cv.drawChessboardCorners(img,(w,h),corners,ret)
        #在棋盘定制图上绘制角点；corners为初始角点坐标；ret为标志位，是否完全探测
        i+=1
        cv.imwrite('conimg'+str(i)+'.jpg',img)
        cv.waitKey(1500)
    print(len(img_points))
    cv.destroyAllWindows()
#相机标定，返回值是相机内参数
ret,mtx,dist,rvecs,tvecs=cv.calibrateCamera(obj_points,img_points,size,None,None)

print('ret:',ret)
print('内参数矩阵:\n',mtx)
print('畸变系数:\n',dist)
print('旋转向量:\n',rvecs)
print('平移向量:\n',tvecs)

#相机标定：
#1.准备标定图片；2.对每一张标定图片，提取角点信息；3.对每一张图片进一步提取亚像素角点信息
#4.在棋盘标定图上绘制找到的内角点（非必需）；5.相机标定；6.标定结果评价；7.矫正
